#include <Arduino.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <ESPAsyncWebServer.h>

const char* ssid = "HA";
const char* password = "ha@123_456";
const char* serverURL = "http://192.168.153.23:8080/api/v1/device/report";

const char* id = "light_b";
const char* name = "两个灯";
String deviceURL;

const int board_led_left = 12;
const int board_led_right = 13;

const char* leftLedSwitchId = "left_led_switch";
const char* rightLedSwitchId = "right_led_switch";
boolean leftLedStatus = false;
boolean rightLedStatus = false;

// 创建一个异步 Web 服务器实例
AsyncWebServer server(80);

/**
 * 设备状态 
 */
String getSatusStr() {
  
  StaticJsonDocument<200> leftBooleanParamDoc;
  leftBooleanParamDoc["id"] = leftLedSwitchId;
  leftBooleanParamDoc["name"] = "左灯开关";
  leftBooleanParamDoc["value"] = leftLedStatus;
  leftBooleanParamDoc["controllable"] = true;

  StaticJsonDocument<200> rightBooleanParamDoc;
  rightBooleanParamDoc["id"] = rightLedSwitchId;
  rightBooleanParamDoc["name"] = "右灯开关";
  rightBooleanParamDoc["value"] = rightLedStatus;
  rightBooleanParamDoc["controllable"] = true;

  StaticJsonDocument<400> devDoc;
  devDoc["id"] = id;
  devDoc["name"] = name;
  devDoc["url"] = deviceURL;


  JsonArray parameterBooleanList = devDoc.createNestedArray("parameterBooleanList");
  parameterBooleanList.add(leftBooleanParamDoc);
  parameterBooleanList.add(rightBooleanParamDoc);

  String devDocStr;
  serializeJson(devDoc, devDocStr);
  return devDocStr;
}

void report() {
  HTTPClient http;
  http.begin(serverURL);                                                       // 初始化HTTP请求
  http.addHeader("Content-Type", "application/json");                          // 设置请求头

  // 创建JSON请求体
  int httpResponseCode = http.POST(getSatusStr()); // 发送POST请求

  if (httpResponseCode == 200) {
    Serial.print("HTTP Response code: ");
    Serial.println(httpResponseCode);
    String payload = http.getString(); // 获取服务器返回的数据
    Serial.println("Response: ");
    Serial.println(payload);
  } else {
    Serial.print("Error on HTTP request: ");
    Serial.println(httpResponseCode);
  }
  http.end(); // 结束HTTP请求，释放资源
}

void reportTask(void *pvParameters) {
  while (1) {
    Serial.println("Report Task is running...");
    report();
    vTaskDelay(5000 / portTICK_PERIOD_MS);
  }
}

void simpleTask(void *pvParameters) {
  while (1) {
    Serial.println("Simple Task is running...");
    digitalWrite(board_led_right, LOW);
    vTaskDelay(2000 / portTICK_PERIOD_MS);
    digitalWrite(board_led_right, HIGH);
    vTaskDelay(2000 / portTICK_PERIOD_MS);
  }
}

void setup() {
  pinMode(board_led_left, OUTPUT);
  pinMode(board_led_right, OUTPUT);
  digitalWrite(board_led_left, LOW);
  digitalWrite(board_led_left, LOW);

  Serial.begin(115200);

  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  Serial.println("Connected to WiFi");  
  deviceURL = WiFi.localIP().toString();
  Serial.println(deviceURL);


  // 设置路由和处理函数
  server.on("/api/v1/control", HTTP_POST, [](AsyncWebServerRequest *request) {
    // 这里可以处理请求头等信息
    request->send(200, "application/json", getSatusStr());
  }, NULL, [](AsyncWebServerRequest *request, uint8_t *data, size_t len, size_t index, size_t total) {
    // 处理请求体
    String requestBody;
    // 将接收到的数据块拼接到 requestBody 中
    for (size_t i = 0; i < len; i++) {
      requestBody += (char)data[i];
    }

    // 如果已经接收到完整的请求体
    if (index + len == total) {
      Serial.println("Received complete POST request body:");
      Serial.println(requestBody);

      // 解析 JSON 数据
      StaticJsonDocument<512> doc;  // 根据需要调整大小
      DeserializationError error = deserializeJson(doc, requestBody);

      if (!error) {
        // 解析成功，提取数据
        leftLedStatus = doc[leftLedSwitchId].as<boolean>();
        rightLedStatus = doc[rightLedSwitchId].as<boolean>();
        if (leftLedStatus) {
          digitalWrite(board_led_left, HIGH);
        } else {
          digitalWrite(board_led_left, LOW);
        }

        if (rightLedStatus) {
          digitalWrite(board_led_right, HIGH);
        } else {
          digitalWrite(board_led_right, LOW);
        }

        // 返回响应
        request->send(200, "application/json", getSatusStr());
      } else {
        // 解析失败
        Serial.println("Failed to parse JSON");
        request->send(400, "text/plain", "Invalid JSON format");
      }

      // 清空 requestBody 以准备下一次请求
      requestBody = "";
    }
  });

  // 启动 HTTP 服务器
  server.begin();

  xTaskCreate(reportTask, "ReportTask", 8192, NULL, 1, NULL);
  // xTaskCreate(simpleTask, "SimpleTask", 4096, NULL, 1, NULL);
}

void loop() {
  // FreeRTOS 调度器接管后，loop() 不再执行
}